昨天有講到除了可以使用Layer API來建立Model之外
其實還有一種Core API可以建立model並進行訓練
Core API跟前幾天學的不太一樣
而且也不是很易於使用
自己要處理的事情變得很多
而且也不能儲存或載入模型,感覺好像在找自己麻煩
不過今天都花時間了解了
而且Google說這樣可以創造更有彈性和更能掌控的模型
我就以Core API改寫一下
var w1 = tf.variable(tf.randomNormal([1, 20]));
var b1 = tf.variable(tf.randomNormal([20]));
var w2 = tf.variable(tf.randomNormal([20, 50]));
var w3 = tf.variable(tf.randomNormal([50, 10]));
var w4 = tf.variable(tf.randomNormal([10, 1]));
var b4 = tf.variable(tf.randomNormal([1]));
function createCoreModel(x) {
return function (x) {
return x.mul(w1).add(b1).matMul(w2).sigmoid().matMul(w3).sigmoid().matMul(w4).add(b4)
};
}
視覺化結果
let history=[];
async function visualize_loss(size,epochs){
const data=Array(epochs).fill(0);
history.map((element)=>{
data[element.epoch]+=element.loss;
})
const avg_loss=data.map((x)=>{
return x/size;
})
const series1 = avg_loss.map((y, x) => ({ x, y, }));
const plot = { values: [series1] }
const surface = { name: 'Zoomed Line Chart', tab: 'Visor' };
tfvis.render.linechart(surface, plot, { zoomToFit: true });
}
再來是訓練過程
async function trainCoreModel(model, data) {
const batchSize = 16;
const epochs = 5;
const inputs = tf.data.array(data.inputs.arraySync());
const labels = tf.data.array(data.labels.arraySync());
const size = data.inputs.arraySync().length;
const dataset = tf.data.zip({
inputs,
labels
}).shuffle(size).batch(batchSize);
const optimizer = tf.train.adam();
for (let epoch = 0; epoch <epochs; epoch++) {
await dataset.forEachAsync(({
inputs,
labels
}) => {
const batchdata = [inputs.arraySync(), labels.arraySync()];
let index = 0;
batchdata[0].map(() => {
optimizer.minimize(() => {
const predYs = model(tf.tensor(batchdata[0][index])).as1D();
const labels = tf.tensor(batchdata[1][index])
const loss = tf.losses.meanSquaredError(labels, predYs);
history.push({epoch:epoch,loss:loss.arraySync()});
return loss;
}, [w1, b1, w2, w3, w4, b4]);
index++;
})
});
}
visualize_loss(size,epochs);
}
再把這裡改成
var model;
async function runTensorFlow() {
// model = createModel();
// const data = await getData();
// const tensorData = convertToTensor(data);
// await trainModel(model, tensorData.inputs, tensorData.labels);
// console.log('Done Training');
// const predictedData = getPrediction(model, tensorData);
// visualiztionPrediction(data, predictedData);
model = createCoreModel();
const data = await getData();
const tensorData = convertToTensor(data);
await trainCoreModel(model,tensorData );
// await trainModel(model, tensorData.inputs, tensorData.labels);
// console.log('Done Training');
// const predictedData = getPrediction(model, tensorData);
// visualiztionPrediction(data, predictedData);
}
document.addEventListener('DOMContentLoaded', runTensorFlow);
得到預測結果
function getPrediction(model, normalizationData) {
const {
inputMax,
inputMin,
labelMin,
labelMax
} = normalizationData;
return tf.tidy(() => {
//tf.linspace(start_value,end_value,number_of_value);
const input_x_tensor = tf.linspace(0, 1, 100);
const input_x = input_x_tensor.arraySync();
const preds = tf.tensor(input_x.map((x) => {
return model(tf.tensor(x)).arraySync();
}))
//轉回原本的數= 數字*(最大值-最小值)+最小值
const toOrignalX = input_x_tensor
.mul(inputMax.sub(inputMin))
.add(inputMin);
const toOrignalY = preds
.mul(labelMax.sub(labelMin))
.add(labelMin);
//tensor.dataSync() return data from tensor to array
return [toOrignalX.dataSync(), toOrignalY.dataSync()];
});
}
組在一起
var model;
async function runTensorFlow() {
model = createCoreModel();
const data = await getData();
const tensorData = convertToTensor(data);
await trainCoreModel(model, tensorData);
const predictedData = getPrediction(model, tensorData);
visualiztionPrediction(data, predictedData);
}
document.addEventListener('DOMContentLoaded', runTensorFlow);
使用Core API真的超麻煩的
可能是我對TensorFlow.js不太熟
網路上找到的範例也不多
雖然能跑得出答案
但明顯我這種作法肯定有問題
變得很慢
而且很容易當掉
在接下來的幾天,我應該能不用就不用Core API
寫一個範例要花太多時間了